home *** CD-ROM | disk | FTP | other *** search
- // CmString.cpp
- // -----------------------------------------------------------------
- // Compendium - C++ Container Class Library
- // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
- // -----------------------------------------------------------------
- // Character string implementation.
- // -----------------------------------------------------------------
-
- #include <ctype.h>
- #include <string.h>
- #include <cm/include/cmstring.h>
- #include <stdio.h>
-
-
- // Define "stricmp" and "strnicmp" for machines that don't support it.
- //
- #if !defined(__TURBOC__)
- int stricmp(const char* a, const char* b)
- {
- CmString A(a), B(b);
- A.toUpper(); B.toUpper();
- return strcmp(A, B);
- }
- int strnicmp(const char* a, const char* b, int n)
- {
- CmString A(a), B(b);
- A.toUpper(); B.toUpper();
- return strncmp(A, B, n);
- }
- #endif
-
-
- // Initialize the case sensitive compare flag.
- //
- Bool CmString::_caseSensitive = TRUE;
-
-
- // "CmString" is the default string constructor.
- //
- CmString::CmString(const char *letters)
- {
- _text = NULL;
- copy(letters);
- }
-
-
- // "CmString" constructs a string of size N and fills the string with
- // N copies of the specified character.
- //
- CmString::CmString(int N, char C)
- {
- _text = new char[N+1];
- if (_text)
- {
- for (int ii = 0; ii < N; ii++)
- _text[ii] = C;
- _text[N] = '\0';
- }
- }
-
-
- // "CmString" constructs a string from the specified substring.
- //
- CmString::CmString(const CmSubString& S)
- {
- _text = (S._sl > 0) ? new char[S._sl+1] : NULL;
- if (_text)
- {
- strncpy(_text, S._sp, S._sl);
- _text[S._sl] = '\0';
- }
- }
-
-
- // "CmString" is the string copy constructor.
- //
- CmString::CmString(const CmString &S)
- {
- _text = NULL;
- copy(S._text);
- }
-
-
- // "~CmString" is the string destructor.
- //
- CmString::~CmString()
- {
- delete[] _text;
- }
-
-
- // "index" returns the first occurrence of the specified character
- // in the string.
- //
- int CmString::index(char chr) const
- {
- int pos = -1;
- if (_text && strlen(_text) > 0)
- {
- int ii = 0, ln = strlen(_text);
- while (ii < ln && pos == -1)
- if (chr == _text[ii++]) pos = ii - 1;
- }
- return pos;
- }
-
-
- // "LeftJustify" left justifies the string within itself.
- //
- void CmString::leftJustify()
- {
- int lnth = strlen(_text);
- char *letters = new char[lnth+1];
- strcpy(letters, _text);
-
- int ii = 0;
- while (isspace(letters[ii])) ii++;
- if (ii == lnth)
- _text = NULL;
- else if (ii > 0)
- {
- for (int jj = 0; jj < (lnth-ii); jj++)
- letters[jj] = letters[ii + jj];
- letters[lnth - ii] = '\0';
- }
-
- copy(letters);
- delete[] letters;
- }
-
-
- // "rightJustify" rights justifies the string within itself.
- //
- void CmString::rightJustify()
- {
- if (!_text) return;
-
- int lnth = strlen(_text);
- char *letters = new char[lnth+1];
- strcpy(letters, _text);
-
- int ii = lnth-1;
- while (isspace(letters[ii]) && ii >= 0) ii--;
-
- if (ii == lnth-1) return;
-
- if (ii < 0)
- {
- copy(NULL);
- return;
- }
-
- int howmany = ii + 1, jj = lnth;
- while (ii >= 0)
- letters[jj--] = letters[ii--];
-
- for (ii = 0; ii < howmany; ii++)
- letters[ii] = ' ';
-
- copy(letters);
- delete[] letters;
- }
-
-
- // "trim" trims the leading and trailing blank characters from the
- // string.
- //
- void CmString::trim()
- {
- char* p = _text;
- while (isspace(*p)) p++;
- if (p != _text) strcpy(_text, p);
- int cc = strlen(_text);
- if (cc) for (p = _text + cc - 1; isspace(*p); p--) *p = '\0';
- int lnth = strlen(_text);
- char* newText = (lnth > 0) ? new char[lnth + 1] : NULL;
- if (lnth > 0) strcpy(newText, _text);
- delete[] _text;
- _text = newText;
- }
-
-
- // "toLower" converts all characters in this string to lower case.
- //
- void CmString::toLower()
- {
- int i = strlen(_text);
- char *q = _text;
- while (i--) { if (*q >= 'A' && *q <= 'Z') *q = *q - 'A' + 'a'; q++; }
- }
-
-
- // "toUpper" converts all characters in this string to upper case.
- //
- void CmString::toUpper()
- {
- int i = strlen(_text);
- char *q = _text;
- while (i--) { if (*q >= 'a' && *q <= 'z') *q = *q - 'a' + 'A'; q++; }
- }
-
-
- // "()" substring operator returns a substring of this string.
- //
- CmSubString CmString::operator()(int start, int stop)
- {
- int st = (start < 0) ? 0 : ((start >= length()) ? length() - 1 : start);
- int en = (stop < 0) ? 0 : ((stop >= length()) ? length() - 1 : stop);
- if (start > stop) start = stop;
- return CmSubString(*this, st, en);
- }
-
-
- // "()" substring operator returns a substring of this string.
- //
- const CmSubString CmString::operator()(int start, int stop) const
- {
- int st = (start < 0) ? 0 : ((start >= length()) ? length() - 1 : start);
- int en = (stop < 0) ? 0 : ((stop >= length()) ? length() - 1 : stop);
- if (start > stop) start = stop;
- return CmSubString(*this, st, en);
- }
-
-
- // "isEqual" checks to see if the input object is a string and it they
- // are equal.
- //
- Bool CmString::isEqual(CmObject* pObj) const
- {
- if (pObj->isA("CmString")) return (*this == ((CmString&) *pObj));
- else return CmObject::isEqual(pObj);
- }
-
-
- // "compare" does a comparison of the input object and this string and
- // returns -1 if this is < object, 0 if equal, 1 if this is greater.
- //
- int CmString::compare(CmObject* pObj) const
- {
- if (!pObj->isA("CmString")) return CmObject::compare(pObj);
- CmString& str = (CmString&) *pObj;
- return ((str == *this) ? 0 : ((*this > str) ? 1 : -1));
- }
-
-
- // "hash" hashes the character string.
- //
- unsigned CmString::hash(unsigned m) const
- {
- unsigned h;
- char* v = _text;
- for (h = 0; *v != '\0'; v++) h = (64 * h + *v) % m;
- return h;
- }
-
-
- // "readFrom" reads text into this string from the specified input
- // stream operator.
- //
- void CmString::readFrom(istream& is)
- {
- char buff[1024];
- is.getline(buff, sizeof(buff));
- copy(buff);
- }
-
-
- // "write" writes the string length and text to the specified reserve
- // binary file.
- //
- Bool CmString::write(CmReserveFile& file) const
- {
- return file.write(_text);
- }
-
-
- // "read" reads the string length and text from the specified reserve
- // binary file.
- //
- Bool CmString::read(CmReserveFile& file)
- {
- int lnth;
- if (!file.read(lnth)) return FALSE;
- if (lnth == 0)
- {
- copy(NULL);
- return TRUE;
- }
-
- char* s = (lnth > 0) ? new char[lnth] : NULL;
- if (!s) return FALSE;
- if (!file.read(s, (unsigned) lnth)) return FALSE;
- copy(s);
- delete[] s;
- return TRUE;
- }
-
-
- // "+" operator concatenates this string and an input string returning the
- // resultant string.
- //
- CmString CmString::operator+(const CmString &S) const
- {
- CmString NewString = *this;
- NewString.append(S);
- return NewString;
- }
-
-
- // "+=" operator concatenates an input string on to the end of this string.
- //
- CmString& CmString::operator+=(const CmString &S)
- {
- append(S);
- return *this;
- }
-
-
- // "+" operator concatenates this string and an input string returning the
- // resultant string.
- //
- CmString CmString::operator+(const char* s) const
- {
- CmString NewString = *this;
- NewString.append(CmString(s));
- return NewString;
- }
-
-
- // "+=" operator concatenates an input string on to the end of this string.
- //
- CmString& CmString::operator+=(const char* s)
- {
- append(CmString(s));
- return *this;
- }
-
- // "+" operator concatenates the input strings returning the result.
- //
- CmString operator+(const char* s, const CmString& S)
- {
- CmString NewString = s;
- NewString.append(S);
- return NewString;
- }
-
-
- // "copy" copies a character array into this string.
- //
- void CmString::copy(const char *letters)
- {
- if (_text) delete[] _text;
- if (letters)
- {
- _text = new char[strlen(letters)+1];
- strcpy(_text, letters);
- }
- else
- _text = NULL;
- }
-
-
- // "append" appends the contents of an input string onto the end of this
- // string.
- //
- void CmString::append(const CmString &S)
- {
- int len1 = (_text) ? strlen(_text) : 0;
- int len2 = (S._text) ? strlen(S._text) : 0;
- int lnth = len1 + len2;
- char *letters = (lnth > 0) ? new char[lnth + 1] : NULL;
-
- if (len1 && !len2)
- strcpy(letters, _text);
- else if (len2 && !len1)
- strcpy(letters, S._text);
- else if (len1 && len2)
- {
- strcpy(letters, _text);
- letters = strcat(letters, S._text);
- }
- else
- letters = NULL;
-
- if (_text) delete[] _text;
- _text = letters;
- }
-
-
- // "<" checks if the specified string is less than this.
- //
- Bool CmString::operator<(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, S._text) < 0);
- else
- return (stricmp(_text, S._text) < 0);
- }
-
-
- // "<=" checks if the specified string is less than or equal to this.
- //
- Bool CmString::operator<=(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, S._text) <= 0);
- else
- return (stricmp(_text, S._text) <= 0);
- }
-
-
- // ">" checks if the specified string is greater than this.
- //
- Bool CmString::operator>(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, S._text) > 0);
- else
- return (stricmp(_text, S._text) > 0);
- }
-
-
- // ">=" checks if the specified string is greater than or equal to this.
- //
- Bool CmString::operator>=(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, S._text) >= 0);
- else
- return (stricmp(_text, S._text) >= 0);
- }
-
-
- // "==" checks if the specified string is equal to this.
- //
- Bool CmString::operator==(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, S._text) == 0);
- else
- return (stricmp(_text, S._text) == 0);
- }
-
-
- // "!=" checks if the specified string is not equal to this.
- //
- Bool CmString::operator!=(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, S._text) != 0);
- else
- return (stricmp(_text, S._text) != 0);
- }
-
-
- // "<" checks if the specified string is less than this.
- //
- Bool CmString::operator<(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, s) < 0);
- else
- return (stricmp(_text, s) < 0);
- }
-
-
- // "<=" checks if the specified string is less than or equal to this.
- //
- Bool CmString::operator<=(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, s) <= 0);
- else
- return (stricmp(_text, s) <= 0);
- }
-
-
- // ">" checks if the specified string is greater than this.
- //
- Bool CmString::operator>(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, s) > 0);
- else
- return (stricmp(_text, s) > 0);
- }
-
-
- // ">=" checks if the specified string is greater than or equal to this.
- //
- Bool CmString::operator>=(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, s) >= 0);
- else
- return (stricmp(_text, s) >= 0);
- }
-
-
- // "==" checks if the specified string is equal to this.
- //
- Bool CmString::operator==(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, s) == 0);
- else
- return (stricmp(_text, s) == 0);
- }
-
-
- // "!=" checks if the specified string is not equal to this.
- //
- Bool CmString::operator!=(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strcmp(_text, s) != 0);
- else
- return (stricmp(_text, s) != 0);
- }
-
-
- // "<" checks if string B is less than string A.
- //
- Bool operator<(const char* s, const CmString& S)
- {
- if (CmString::caseSensitive())
- return (strcmp(s, S._text) < 0);
- else
- return (stricmp(s, S._text) < 0);
- }
-
-
- // "<=" checks if string B is less than ior equal to string A.
- //
- Bool operator<=(const char* s, const CmString& S)
- {
- if (CmString::caseSensitive())
- return (strcmp(s, S._text) <= 0);
- else
- return (stricmp(s, S._text) <= 0);
- }
-
-
- // ">" checks if string B is greater than string A.
- //
- Bool operator>(const char* s, const CmString& S)
- {
- if (CmString::caseSensitive())
- return (strcmp(s, S._text) > 0);
- else
- return (stricmp(s, S._text) > 0);
- }
-
-
- // ">=" checks if string B is greater than or equal to string A.
- //
- Bool operator>=(const char* s, const CmString& S)
- {
- if (CmString::caseSensitive())
- return (strcmp(s, S._text) >= 0);
- else
- return (stricmp(s, S._text) >= 0);
- }
-
-
- // "==" checks if string B is equal to string A.
- //
- Bool operator==(const char* s, const CmString& S)
- {
- if (CmString::caseSensitive())
- return (strcmp(s, S._text) == 0);
- else
- return (stricmp(s, S._text) == 0);
- }
-
-
- // "!=" checks if string B is not equal to string A.
- //
- Bool operator!=(const char* s, const CmString& S)
- {
- if (CmString::caseSensitive())
- return (strcmp(s, S._text) != 0);
- else
- return (stricmp(s, S._text) != 0);
- }
-
-
- // "=" assignment copies the contents of the specified string into
- // this substring.
- //
- CmString& CmSubString::operator=(const CmString& S)
- {
- if (_sl == S.length()) strncpy(_sp, S._text, _sl);
- else replace(S._text, S.length());
- return *_st;
- }
-
-
- // "=" assignment copies the contents of the specified substring into
- // this substring.
- //
- CmString& CmSubString::operator=(const CmSubString& S)
- {
- if (_sl == S._sl) strncpy(_sp, S._sp, _sl);
- else replace(S._sp, S._sl);
- return *_st;
- }
-
-
- // "=" assignment copies the contents of the specified string into
- // this substring.
- //
- CmString& CmSubString::operator=(const char* s)
- {
- int cslen = strlen(s);
- if (_sl == cslen) strncpy(_sp, s, _sl);
- else replace(s, cslen);
- return *_st;
- }
-
-
- // "<<" outputs this substring to the specified stream.
- //
- ostream& operator<<(ostream& os, const CmSubString& S)
- {
- char *p = S._sp;
- for (int ii = 0; ii < S._sl; ii++)
- os << *(p++);
- return os;
- }
-
-
- // "CmSubString" constructs a substring from the specified string,
- // starting position, and ending position.
- //
- CmSubString::CmSubString(const CmString& S, int start, int stop)
- {
- _sp = &(S._text[start]);
- _sl = stop - start + 1;
- _st = &((CmString&)S);
- }
-
-
- // "CmSubString" constructs a substring from the specified substring.
- //
- CmSubString::CmSubString(const CmSubString& S)
- {
- _sp = S._sp;
- _sl = S._sl;
- _st = S._st;
- }
-
-
- // "replace" replaces the contents of this substring with the specified
- // string.
- //
- void CmSubString::replace(const char* src, int srclen)
- {
- int tot = (srclen == _sl) ? srclen : ((srclen < _sl) ? srclen : _sl);
- strncpy(_sp, src, tot);
- }
-
-
- // "<" checks if the specified string is less than this.
- //
- Bool CmSubString::operator<(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._text, _sl) < 0);
- else
- return (strnicmp(_sp, S._text, _sl) < 0);
- }
-
-
- // "<=" checks if the specified string is less than or equal to this.
- //
- Bool CmSubString::operator<=(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._text, _sl) <= 0);
- else
- return (strnicmp(_sp, S._text, _sl) <= 0);
- }
-
-
- // ">" checks if the specified string is greater than this.
- //
- Bool CmSubString::operator>(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._text, _sl) > 0);
- else
- return (strnicmp(_sp, S._text, _sl) > 0);
- }
-
-
- // ">=" checks if the specified string is greater than or equal to this.
- //
- Bool CmSubString::operator>=(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._text, _sl) >= 0);
- else
- return (strnicmp(_sp, S._text, _sl) >= 0);
- }
-
-
- // "==" checks if the specified string is equal to this.
- //
- Bool CmSubString::operator==(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._text, _sl) == 0);
- else
- return (strnicmp(_sp, S._text, _sl) == 0);
- }
-
-
- // "!=" checks if the specified string is not equal to this.
- //
- Bool CmSubString::operator!=(const CmString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._text, _sl) != 0);
- else
- return (strnicmp(_sp, S._text, _sl) != 0);
- }
-
-
- // "<" checks if the specified string is less than this.
- //
- Bool CmSubString::operator<(const CmSubString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._sp, _sl) < 0);
- else
- return (strnicmp(_sp, S._sp, _sl) < 0);
- }
-
-
- // "<=" checks if the specified string is less than or equal to this.
- //
- Bool CmSubString::operator<=(const CmSubString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._sp, _sl) <= 0);
- else
- return (strnicmp(_sp, S._sp, _sl) <= 0);
- }
-
-
- // ">" checks if the specified string is greater than this.
- //
- Bool CmSubString::operator>(const CmSubString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._sp, _sl) > 0);
- else
- return (strnicmp(_sp, S._sp, _sl) > 0);
- }
-
-
- // ">=" checks if the specified string is greater than or equal to this.
- //
- Bool CmSubString::operator>=(const CmSubString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._sp, _sl) >= 0);
- else
- return (strnicmp(_sp, S._sp, _sl) >= 0);
- }
-
-
- // "==" checks if the specified string is equal to this.
- //
- Bool CmSubString::operator==(const CmSubString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._sp, _sl) == 0);
- else
- return (strnicmp(_sp, S._sp, _sl) == 0);
- }
-
-
- // "!=" checks if the specified string is not equal to this.
- //
- Bool CmSubString::operator!=(const CmSubString& S) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, S._sp, _sl) != 0);
- else
- return (strnicmp(_sp, S._sp, _sl) != 0);
- }
-
-
- // "<" checks if the specified string is less than this.
- //
- Bool CmSubString::operator<(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, s, _sl) < 0);
- else
- return (strnicmp(_sp, s, _sl) < 0);
- }
-
-
- // "<=" checks if the specified string is less than or equal to this.
- //
- Bool CmSubString::operator<=(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, s, _sl) <= 0);
- else
- return (strnicmp(_sp, s, _sl) <= 0);
- }
-
-
- // ">" checks if the specified string is greater than this.
- //
- Bool CmSubString::operator>(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, s, _sl) > 0);
- else
- return (strnicmp(_sp, s, _sl) > 0);
- }
-
-
- // ">=" checks if the specified string is greater than or equal to this.
- //
- Bool CmSubString::operator>=(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, s, _sl) >= 0);
- else
- return (strnicmp(_sp, s, _sl) >= 0);
- }
-
-
- // "==" checks if the specified string is equal to this.
- //
- Bool CmSubString::operator==(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, s, _sl) == 0);
- else
- return (strnicmp(_sp, s, _sl) == 0);
- }
-
-
- // "!=" checks if the specified string is not equal to this.
- //
- Bool CmSubString::operator!=(const char* s) const
- {
- if (CmString::caseSensitive())
- return (strncmp(_sp, s, _sl) != 0);
- else
- return (strnicmp(_sp, s, _sl) != 0);
- }
-
-
- // "<" checks if the the sub-string is less than the string.
- //
- Bool operator<(const char* s, const CmSubString& S)
- {
- if (CmString::caseSensitive())
- return (strncmp(s, S._sp, S._sl) < 0);
- else
- return (strnicmp(s, S._sp, S._sl) < 0);
- }
-
-
- // "<=" checks if the the sub-string is less than or equal to the string.
- //
- Bool operator<=(const char* s, const CmSubString& S)
- {
- if (CmString::caseSensitive())
- return (strncmp(s, S._sp, S._sl) <= 0);
- else
- return (strnicmp(s, S._sp, S._sl) <= 0);
- }
-
-
- // ">" checks if the the sub-string is greater than the string.
- //
- Bool operator>(const char* s, const CmSubString& S)
- {
- if (CmString::caseSensitive())
- return (strncmp(s, S._sp, S._sl) > 0);
- else
- return (strnicmp(s, S._sp, S._sl) > 0);
- }
-
-
- // ">=" checks if the the sub-string is greater than or equal to the string.
- //
- Bool operator>=(const char* s, const CmSubString& S)
- {
- if (CmString::caseSensitive())
- return (strncmp(s, S._sp, S._sl) >= 0);
- else
- return (strnicmp(s, S._sp, S._sl) >= 0);
- }
-
-
- // "==" checks if the the sub-string is equal to the string.
- //
- Bool operator==(const char* s, const CmSubString& S)
- {
- if (CmString::caseSensitive())
- return (strncmp(s, S._sp, S._sl) == 0);
- else
- return (strnicmp(s, S._sp, S._sl) == 0);
- }
-
-
- // "!=" checks if the the sub-string is not equal to the string.
- //
- Bool operator!=(const char* s, const CmSubString& S)
- {
- if (CmString::caseSensitive())
- return (strncmp(s, S._sp, S._sl) != 0);
- else
- return (strnicmp(s, S._sp, S._sl) != 0);
- }
-
-
- // "caseSensitive" sets the case sensitive compare flag.
- //
- void CmString::caseSensitive(Bool f)
- {
- CmString::_caseSensitive = f;
- }
-
-
- // "caseSensitive" returns the case sensitive compare flag.
- //
- Bool CmString::caseSensitive()
- {
- return CmString::_caseSensitive;
- }
-